Phase 2C: generate the SDK wire types from a Rust emitter#559
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Phase 2C of the versioning remediation: this PR eliminates the remaining “drift surface” between the Rust wire model, the generated JSON schema, and the SDK TypeScript wire types by generating sdk/src/generated/wire.ts via a hand-written Rust emitter (invoked as mxc_schema_gen --ts) and enforcing conformance in CI and unit tests.
Changes:
- Add a Rust TypeScript emitter (
wxc_common::ts_emit) and expose TS emission viamxc_schema_gen --ts. - Add a compile-time conformance oracle test in the SDK plus a CI codegen gate to prevent
wire.tsdrift. - Retire the legacy hand-maintained
0.5.0-alpha-strictstable schema view and update docs accordingly.
Show a summary per file
| File | Description |
|---|---|
| src/tools/mxc_schema_gen/src/main.rs | Adds --ts mode and refactors output handling for schema vs TS emission. |
| src/core/wxc_common/src/wire.rs | Factors out shared schema_value() and adds generate_sdk_types_ts() entrypoint for TS emission. |
| src/core/wxc_common/src/ts_emit.rs | New Rust emitter that walks the schema Value and emits deterministic wire.ts. |
| src/core/wxc_common/src/lib.rs | Exposes ts_emit behind the schema-gen feature. |
| sdk/tests/unit/wire-conformance.test.ts | New compile-time (tsc) conformance oracle between public SDK types and generated wire types. |
| sdk/src/generated/wire.ts | New generated drift-oracle TypeScript wire types (committed output). |
| sdk/README.md | Removes references to the retired 0.5.0-alpha-strict schema view. |
| sdk/package.json | Adds the new wire conformance unit test to the unit test run list. |
| scripts/versioning/check-sdk-types-codegen.js | New CI gate to regenerate wire.ts and diff against committed output (with CRLF/LF normalization). |
| schemas/stable/mxc-config.schema.0.5.0-alpha-strict.json | Deletes the hand-maintained strict stable schema view. |
| docs/schema-codegen.md | Documents the new generated SDK wire-types drift oracle and updated roadmap. |
| .github/workflows/Versioning.Checks.Job.yml | Wires the new SDK wire-types codegen gate into Versioning Checks. |
| .github/copilot-instructions.md | Updates repo conventions to reflect removal of -strict stable schemas and addition of generated SDK wire types. |
Copilot's findings
- Files reviewed: 12/13 changed files
- Comments generated: 2
Member
Author
|
Addressed both review comments in 74a22c0 (doc/label accuracy, no behavior change):
|
Collaborator
|
To generate typescript types from the rust types should we be using https://crates.io/crates/ts-rs ? |
74a22c0 to
122aa69
Compare
c2fa61b to
ab4b36b
Compare
bbonaby
reviewed
Jun 25, 2026
This PR changes the SDK's wire TypeScript types to be generated from the Rust wire model by a hand-written emitter (no third-party generator), guarded by a conformance test and a CI gate so they cannot drift, and retires the hand-maintained 0.5.0-alpha-strict stable schema view. This closes the third versioning drift surface: a wire-model change ripples to the Rust model, the JSON schema, and the SDK types, or it fails CI. Details: - Add wxc_common::ts_emit, a Rust emitter that walks the generated schema value and emits TypeScript (string-union enums, closed/open objects, $ref, anyOf [T, null], arrays, scalars). Refactor wire.rs so the JSON-schema renderer and the new generate_sdk_types_ts() share a schema_value() helper; the JSON schema output stays byte-for-byte identical. - Add a --ts mode to mxc_schema_gen that emits the committed sdk/src/generated/wire.ts (an internal drift oracle, not public API). - Add sdk/tests/unit/wire-conformance.test.ts: compile-time assertions that sdk/src/types.ts conforms to the generated wire shape - bidirectional and exact (public/wire field rename/removal, wire-only field additions, and enum narrowing and widening), at the root and every leaf, with each intentional divergence pinned to a documented allow-list. - Add scripts/versioning/check-sdk-types-codegen.js, a CI gate that runs the emitter and diffs the committed wire.ts (mirrors check-schema-codegen.js); wire it into the Versioning Checks job. No new npm or cargo dependency. - Retire schemas/stable/mxc-config.schema.0.5.0-alpha-strict.json and update the doc references (sdk/README.md, docs/schema-codegen.md, copilot-instructions.md). Tests: - cargo test --workspace; cargo fmt --all -- --check; cargo clippy --workspace --all-targets -- -D warnings; ts_emit unit tests. - Schema codegen, SDK wire-types codegen, and config corpus (169/169) gates. - cd sdk && npm test. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Generated-with: claude-opus-4.8
ab4b36b to
b529476
Compare
…atives) This PR addresses two review comments from bbonaby on the 2C PR (#559): Details: - Reword the header comment in check-sdk-types-codegen.js to drop the internal "Phase 2C, option C" / "options A/B" vocabulary, matching the repo convention of keeping phase/spike naming out of shipped files. It now just describes what the gate does. - Add an "Alternatives considered" subsection to docs/schema-codegen.md explaining why the SDK wire types use a hand-written Rust emitter (drift oracle) rather than generating the public API directly or using a third-party schema->TS generator, plus a note on the FlatBuffers option. Makes the rationale discoverable for future readers. Tests: - node scripts/versioning/check-sdk-types-codegen.js (gate still green; docs/comment-only change, generated wire.ts unaffected). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Generated-with: claude-opus-4.8
bbonaby
approved these changes
Jun 26, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Phase 2C of the versioning remediation. Closes the third drift surface - the Rust wire model, the generated JSON schema, and the SDK TypeScript types - by emitting the SDK wire types from a hand-written Rust emitter (
wxc_common::ts_emit, exposed viamxc_schema_gen --ts) with no new npm or cargo dependency, asserting the hand-written public types conform to them, and retiring the hand-maintained0.5.0-alpha-strictstable schema view.A wire-model change now ripples to all three surfaces or fails CI; it cannot drift silently.
What changed
src/core/wxc_common/src/ts_emit.rswalks the generated schema value and emitssdk/src/generated/wire.ts(an internal drift oracle, not public API).wire.rsis refactored to share aschema_value()helper; the JSON schema output stays byte-for-byte identical.mxc_schema_gen --tsmode emits the committed TS; the existing schema mode is unchanged.sdk/tests/unit/wire-conformance.test.tsasserts (attsctime) thatsdk/src/types.tsconforms to the generated wire shape - bidirectional and exact: catches public/wire field rename/removal, wire-only field additions the SDK forgot to expose, and enum narrowing and widening, at the root and every leaf. Every intentional divergence is pinned to a documented allow-list.scripts/versioning/check-sdk-types-codegen.jsruns the emitter and diffs the committedwire.ts(mirrorscheck-schema-codegen.js); wired into the Versioning Checks job.schemas/stable/mxc-config.schema.0.5.0-alpha-strict.jsonand updates the three doc references.Review
Converged through two independent, model-diverse adversarial review loops (GPT-5.3-Codex and GPT-5.5) before this PR; the bidirectional/exact conformance design is the result of findings from both.
Verification
cd sdk && npm test-> 181 pass (incl. the conformance oracle)cargo test -p wxc_common --features schema-gen ts_emit-> 3 pass; clippy + fmt cleannode scripts/versioning/check-sdk-types-codegen.js-> OKnode scripts/versioning/check-schema-codegen.js-> OK (schema byte-identical)node scripts/versioning/validate-configs.js-> 169/169Follow-up (non-blocking)
A companion conformance block for the state-aware public types (
sdk/src/state-aware-types.tsvs theIsolationSession*wire defs), flagged by both reviewers.Microsoft Reviewers: Open in CodeFlow